package edu.gatech.wms.controllers;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;

import edu.gatech.wms.models.DBInterface;
import edu.gatech.wms.models.Database;
import edu.gatech.wms.models.User;

public class Login implements DBInterface {
	
	public static final String ACTIVE_KEY = "ACTIVE_KEY";
	public static final String ITEM_KEY = "ITEM_KEY";
	public static final String USER_KEY = "USER_KEY";
	public static final String IS_ADMIN = "IS_ADMIN";
	public static final int LOGIN_LOCKED = -1;
	public static final int LOGIN_FAIL = 0;
	public static final int LOGIN_SUCCESS = 1;
	
	
	private static final int MAX_TRIES = 3;
	private static Login singletonLogin;
	
	private static boolean isAdmin;
	private static int activeKey;

	private Login() {
	}

	public static Login getLoginObject() {
		if (singletonLogin == null) {
			singletonLogin = new Login();
		}
		return singletonLogin;
	}
	public static void logout() {
		activeKey = 0;
		isAdmin = false;
	}
	/**
	 * 
	 * @return	A unique session key that could be passed between methods to maintain security
	 */
	public static int getActiveKey() {
		return activeKey;
	}
	
	
	private static String hashPassword(String _password ) {
		
		byte[] encodedPassword = new byte[32];
		try {
			MessageDigest mySha1 = MessageDigest.getInstance("SHA-256");
			mySha1.update(_password.getBytes());
			encodedPassword = mySha1.digest();
			mySha1.reset();
			
			return String.format("%0" + (encodedPassword.length*2) + "X", new BigInteger(1, encodedPassword));
		} catch (NoSuchAlgorithmException e) {
			
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 
	 * @param email Submitted emailaddress
	 * @param password Submitted Password
	 * @return	True if both match existing DB User Object
	 */
	public int authUser(String email, String _password) {
		//email = email.toLowerCase(Locale.getDefault());
		User user = dbMain.queryUser(email);
		
		if (user.equals( Database.getNullUser() ) ) {	// If this isn't the nullUser increase try count
			return LOGIN_FAIL;
		}
		
		if (_password.length() < 8 ) {
			//increments tries if unsuccessful and locks account if 3 unsuccessful tries occurs
			user.incrementLockout();
			dbMain.save(user);
			return LOGIN_FAIL;
		}
		
		
		if (user.getLockedStatus()) {
			return LOGIN_LOCKED; 
		}
		
		String encodedPassword = hashPassword(_password);
		
		if (user.getPassword().equals(encodedPassword)) {
			user.resetLockout();	// Successful match, reset counter
			dbMain.save(user);
			activeKey = user.getId();
			isAdmin = user.getAdmin();
			return LOGIN_SUCCESS;
		}  
    
		user.incrementLockout();
		dbMain.save(user);
		
		if (user.getTryCount() == MAX_TRIES ) {
			user.setLockedStatus(true);
			dbMain.save(user);
		}
		return LOGIN_FAIL;
	}

	/**
	 * 
	 * @return admin status of account
	 */
	public boolean getIsAdmin()
	{
		return isAdmin;
	}
}